﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Collections;
using CalemShop.Forms;

namespace CalemShop
{
    public partial class FrmBarcodePrinter : FrmBaseDock
    {
        //Verdana
        //Bar-Code 39 or Code 128 or EanBwrP72Tt
        private Font fontCode39 = new Font("Bar-Code 39", 20);
        //private Font fontCode39 = new Font("Code 128", 22);
        //private Font fontCode39 = new Font("EanBwrP36Tt", 36);
        private Font fontALias = new Font("Verdana", 6);
        private const int translateX = 90;
        private const int translateY = 20;
        private const int pWidth = 798;
        private const int pHeight = 1100;

        private const int pWidthStyle1 = 600;
        private const int pHeightStyle1 = 750;


        private const int padding = 2;

        private const int paddingPerLine = 23;

        private const int labelW = 195;
        private const int labelH = 52;
        private int limitColumNum = pWidth / (labelW + padding);
        private int limitRowNum = pHeight / (labelH + padding);

        private int limitColumNumStyle1 = pWidthStyle1 / (labelW + padding);
        private int limitRowNumStyle1 = pHeightStyle1 / (labelH + padding);

        private int columNum = pWidth / (labelW + padding);
        private int rowNum = pHeight / (labelH + padding);

        private int columNumStyle1 = pWidthStyle1 / (labelW + padding);
        private int rowNumStyle1 = pHeightStyle1 / (labelH + padding);


        private Rectangle[,] rects = null;
        private string[,] barcodes = null;
        private decimal amount = 0;
        private int totalPageNum = 0;
        private int printedPage = 0;
        private float printedTranslateY = 0;
        public bool useFromInputStock = false;
        public ArrayList barcodeValues = null;

        public Hashtable itemMap = null;
        PrintDocument doc = new PrintDocument();
        public FrmBarcodePrinter()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);
            doc.PrinterSettings.PrinterName = RuntimeData.GetPrinterName();
        }


        public FrmBarcodePrinter(FrmCalemShop shop)
            : base(shop)
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);
            doc.PrinterSettings.PrinterName = RuntimeData.GetPrinterName();
        }


        void initPlayout(int page)
        {
            if (chStyle1.Checked)
            {
                initPlayoutStyle1(page);
                return;
            }

            if (page <= 0)
            {
                page = 1;
            }
            totalPageNum = page;
            rowNum = page * (pHeight / (labelH + 2 * padding));
            rects = new Rectangle[rowNum, columNum];
            barcodes = new string[rowNum, columNum];
            int x = 0;
            int y = 0;
            for (int r = 0; r < rowNum; r++)
            {
                y = r * labelH;
                if (r > 0)
                {
                    y = r * (labelH + 2 * padding);
                }
                else
                {
                    y = r * labelH;
                }
                for (int c = 0; c < columNum; c++)
                {
                    if (c > 0)
                    {
                        x = c * (labelW + padding);
                    }
                    else
                    {
                        x = c * labelW;
                    }
                    rects[r, c] = new Rectangle(x, y, labelW, labelH);
                }
            }

        }

        void initPlayoutStyle1(int page)
        {
            if (page <= 0)
            {
                page = 1;
            }

            totalPageNum = page;
            rowNumStyle1 = page * (pHeightStyle1 / (labelH + paddingPerLine));
            rects = new Rectangle[rowNumStyle1, columNumStyle1];
            barcodes = new string[rowNumStyle1, columNumStyle1];
            int x = 0;
            int y = 0;
            for (int r = 0; r < rowNumStyle1; r++)
            {
                if (r > 0)
                {
                    y = r * (labelH + paddingPerLine);
                }
                else
                {
                    y = r * labelH + padding;
                }

                for (int c = 0; c < columNumStyle1; c++)
                {
                    if (c > 0)
                    {
                        x = padding + c * (labelW + 2 * padding);
                    }
                    else
                    {
                        x = padding + c * labelW;
                    }
                    rects[r, c] = new Rectangle(x, y, labelW, labelH);
                }
            }

        }

        void doc_PrintPage(object sender, PrintPageEventArgs e)
        {
            e.Graphics.TranslateTransform(0, -printedTranslateY);
            doPaintLayOut(e.Graphics);
            
            if (printedPage < totalPageNum - 1 && totalPageNum > 1)
            {
                e.HasMorePages = true;
                printedPage++;
            }
            else
            {
                e.HasMorePages = false;
                e.Graphics.ResetTransform();
                printedTranslateY = 0;
               
                return;
            }
        }

        private void doPaintLayOut(Graphics g)
        {
            //g.FillRectangle(Brushes.White, 0, 0, pWidth, pHeight);
            g.Clear(Color.White);
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;
            float fontH = fontCode39.GetHeight(g);
            float fontAliasH = fontALias.GetHeight(g);
            int cNum = columNum;
            int cRow = rowNum;
            if (chStyle1.Checked)
            {
                cNum = columNumStyle1;
                cRow = rowNumStyle1;
            }

            bool breakPage = false;
            
            for (int r = 0; r < cRow; r++)
            {
                if (breakPage)
                {
                    break;
                }

                for (int c = 0; c < cNum; c++)
                {
                    Rectangle rect = rects[r, c];
                    if (chStyle1.Checked)
                    {
                        rect = new Rectangle();
                        rect.X = rects[r, c].X + translateX;
                        rect.Y = rects[r, c].Y + translateY;
                        rect.Width = rects[r, c].Width;
                        rect.Height = rects[r, c].Height;
                    }

                    
                    /*if (rects[r, c].Bottom < printedPage * pHeight)
                    {
                        if (printedTranslateY == 0)
                        {
                            printedTranslateY = rects[r, c].Bottom;
                        }
                        
                        break;
                    }*/

                    int limitH = (printedPage + 1) * pHeight;
                    if (chStyle1.Checked)
                    {
                        limitH = (printedPage + 1) * pHeightStyle1;
                    }
                    if (rects[r, c].Bottom > limitH)
                    {
                        //if (printedPage == 0)
                        //{
                        //    g.DrawLine(Pens.Red, 0, rects[r, c].Top, pWidth, rects[r, c].Top);
                        //}
                        //else if (printedPage == 1)
                        //{
                        //    g.DrawLine(Pens.Green, 0, rects[r, c].Top, pWidth, rects[r, c].Top);
                        //}
                        //else if (printedPage == 2)
                        //{
                        //    g.DrawLine(Pens.Blue, 0, rects[r, c].Top, pWidth, rects[r, c].Top);
                        //}

                        //if (printedTranslateY == 0)
                        {
                            printedTranslateY = rects[r, c].Top;
                        }

                        breakPage = true;
                        break;
                    }


                    string value = barcodes[r, c];
                    //g.DrawRectangle(Pens.Black, rects[r, c]);
                    if (!string.IsNullOrEmpty(value))
                    {
                        //Rectangle rectBar = new Rectangle(rect.);
                        g.DrawString(string.Format("*{0}*", value), fontCode39, Brushes.Black, rect, format);
                        RectangleF rectAlias = new RectangleF(rect.X, rect.Y + fontH, rect.Width, fontAliasH);
                        //g.DrawRectangle(Pens.Red, Rectangle.Round(rectAlias));
                        if (itemMap != null && itemMap.ContainsKey(value))
                        {
                            Int32 price = (Int32)itemMap[value];
                            g.DrawString(string.Format("[{0}] {1}", value, price.ToString("#,0 VNĐ")), fontALias, Brushes.Black, rectAlias, format);
                            //g.DrawRectangle(Pens.Red, Rectangle.Round(rectMoney));
                        }
                        else
                        {
                            g.DrawString(string.Format("MA[{0}]", value), fontALias, Brushes.Black, rectAlias, format);
                            //g.DrawRectangle(Pens.Red, Rectangle.Round(rectAlias));
                        }

                    }

                }
            }

            if (chA4.Checked)
            {
                int bottom = pHeight;
                for (int c = 0; c < cNum; c++)
                {
                    Rectangle rect = rects[0, c];
                    g.DrawLine(Pens.Gray, rect.X, rect.Y, rect.X, bottom);
                }

                for (int r = 1; r < cRow; r++)
                {
                    if (rects[r, 0].Bottom >= (printedPage + 1) * pHeight)
                    {
                        continue;
                    }
                    Rectangle rect = rects[r, 0];
                    g.DrawLine(Pens.Gray, rect.X, rect.Y - padding, pWidth, rect.Y - padding);
                }
            }

            //g.DrawLine(Pens.Black, 0, pHeight, pWidth, pHeight);

            //g.Flush();
        }

        private void FrmBarcodePrinter_Load(object sender, EventArgs e)
        {

        }

        private void btPrint_Click_1(object sender, EventArgs e)
        {
            if (doCheckData())
            {
                if (itemMap == null)
                {
                    itemMap = Database.getStockItemPrice((Int32)txtFromMSP.Value, (Int32)txtToMSP.Value);
                }

                printedPage = 0;
                printedTranslateY = 0;
                doc.Print();
            }
        }

        private void txtFromMSP_ValueChanged(object sender, EventArgs e)
        {
            doCheckData();
        }

        public void doCalculatorPages()
        {
            if (barcodeValues == null)
            {
                return;
            }

            amount = barcodeValues.Count;
            if (amount == 0)
            {
                return;
            }

            int labelOnPageNum = limitColumNum * limitRowNum;
            if (chStyle1.Checked)
            {
                labelOnPageNum = limitColumNumStyle1 * limitRowNumStyle1;
            }

            int page = (int)amount / labelOnPageNum;
            if (amount % labelOnPageNum > 0 && amount > 0)
            {
                page++;
            }

            string text = string.Format("In được {0} barcode, {1} page", amount, page);
        }

        private bool doCheckData()
        {
            if (barcodeValues != null)
            {
                return doCheckDataEx();
            }

            if (txtFromMSP.Value == 0 || txtToMSP.Value == 0)
            {
                return false;
            }

            amount = 0;
            for (decimal d = txtFromMSP.Value; d <= txtToMSP.Value; d++)
            {
                amount++;
            }

            if (amount == 0)
            {
                return false;
            }

            int labelOnPageNum = limitColumNum * limitRowNum;
            if (chStyle1.Checked)
            {
                labelOnPageNum = limitColumNumStyle1 * limitRowNumStyle1;
            }

            int page = (int)amount / labelOnPageNum;
            if (amount % labelOnPageNum > 0 && amount > 0)
            {
                page++;
            }



            initPlayout(page);
            int count = 0;
            decimal startNum = txtFromMSP.Value;
            if (chA4.Checked)
            {
                for (int r = 0; r < rowNum; r++)
                {
                    for (int c = 0; c < columNum; c++)
                    {
                        if (count < amount)
                        {
                            count++;
                            barcodes[r, c] = (startNum++).ToString();
                        }
                        else
                        {
                            barcodes[r, c] = string.Empty;
                        }
                    }
                }
            }
            else
            {
                for (int r = 0; r < rowNumStyle1; r++)
                {
                    for (int c = 0; c < columNumStyle1; c++)
                    {
                        if (count < amount)
                        {
                            count++;
                            barcodes[r, c] = (startNum++).ToString();
                        }
                        else
                        {
                            barcodes[r, c] = string.Empty;
                        }
                    }
                }
            }
            string text = string.Format("In được {0} barcode, {1} page", amount, page);
            lbStatus.Text = text;
            return true;
        }

        private bool doCheckDataEx()
        {
            if (barcodeValues == null)
            {
                return false;
            }

            amount = barcodeValues.Count;
            if (amount == 0)
            {
                return false;
            }

            int labelOnPageNum = limitColumNum * limitRowNum;
            if (chStyle1.Checked)
            {
                labelOnPageNum = limitColumNumStyle1 * limitRowNumStyle1;
            }

            int page = (int)amount / labelOnPageNum;
            if (amount % labelOnPageNum > 0 && amount > 0)
            {
                page++;
            }



            initPlayout(page);
            int count = 0;
            int index = 0;
            if (chA4.Checked)
            {
                for (int r = 0; r < rowNum; r++)
                {
                    for (int c = 0; c < columNum; c++)
                    {
                        if (count < amount)
                        {
                            count++;
                            barcodes[r, c] =  barcodeValues[index++].ToString();
                        }
                        else
                        {
                            barcodes[r, c] = string.Empty;
                        }
                    }
                }
            }
            else
            {
                for (int r = 0; r < rowNumStyle1; r++)
                {
                    for (int c = 0; c < columNumStyle1; c++)
                    {
                        if (count < amount)
                        {
                            count++;
                            barcodes[r, c] = barcodeValues[index++].ToString();
                        }
                        else
                        {
                            barcodes[r, c] = string.Empty;
                        }
                    }
                }
            }
            string text = string.Format("In được {0} barcode, {1} page", amount, page);
            lbStatus.Text = text;
            return true;
        }

        private void btView_Click(object sender, EventArgs e)
        {
            if (doCheckData())
            {
                printedPage = 0;
                printedTranslateY = 0;
                if (!useFromInputStock)
                {
                    itemMap = Database.getStockItemPrice((Int32)txtFromMSP.Value, (Int32)txtToMSP.Value);
                }
                else
                {
                    useFromInputStock = false;
                }
                PrintPreviewDialog dlg = new PrintPreviewDialog();
                dlg.Document = doc;
                dlg.ShowDialog();
            }
        }

        private void txtToMSP_ValueChanged(object sender, EventArgs e)
        {
            doCheckData();

        }

        private void FrmBarcodePrinter_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                FrmMain parent = this.MdiParent as FrmMain;
                if (parent != null)
                {
                    parent.frmPrintBarcode = null;
                }
            }
            catch (Exception)
            {
            }
        }
    }
}
